﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using TA.Web.Utils;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using TA.JSON;
using System.IO;

namespace TA.Turbo.Controls
{
	[ParseChildren(true)]
	public class TreeView : BaseComplexValueControl<string>
	{
		#region PUBLIC
		#region INIT
		public TreeView()
		{

		}
		#endregion
		#region PROPS
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public TreeNodeCollection Nodes { get { return this.GetProperty<TreeNodeCollection>("Nodes"); } }
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public NodeTemplateCollection Templates { get { return this._templates; } }
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public List<BaseTemplateMapping> TemplateMappings { get { return this._templateMappings; } }
		#region DEF
		protected static new Properties _clientProperties = Define(BaseComplexValueControl<string>._clientProperties,
			new[] 
			{
				new ListJsonPropertyDefinition<TreeNodeCollection>("Nodes", "N", new TreeNodeCollection()),
			});
		public override Properties ClientProperties
		{
			get
			{
				return _clientProperties;
			}
		}
		#endregion
		#endregion
		#region EVENTS
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public ServerEvent<LoadNodesEventArgs> LoadNodes
		{
			get
			{
				return this.GetServerEvent<LoadNodesEventArgs>("LoadNodes");
			}
		}
		#endregion
		#region METHODS
		public NodeTemplate GetTemplateById(string id)
		{
			foreach (NodeTemplate t in this.Templates)
			{
				if (string.Equals(t.Id, id))
					return t;
			}
			return null;
		}
		#endregion
		#endregion
		#region INTERNAL
		#region VARS
		NodeTemplateCollection _templates = new NodeTemplateCollection();
		List<BaseTemplateMapping> _templateMappings = new List<BaseTemplateMapping>();
		int _templateNodeId = -1;
		#endregion
		#region PROPS
		protected internal override string SerializedValue
		{
			get
			{
				return this.Value;
			}
			set
			{
				this.Value = value;
			}
		}
		#endregion
		#region METHODS
		#region INIT
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			if (!this.get_IsDesignMode())
			{
				foreach (NodeTemplate t in this.Templates)
				{
					t.Init();
					this.Controls.Add(t.Container);
				}
			}

			if (this.TPage != null)
			{
				this.TPage.Load += new EventHandler(TPage_Load);
			}
		}
		void TPage_Load(object sender, EventArgs e)
		{
			this._templateNodeId = -1;
		}
		protected internal override void RegisterIncludes(IncludeCollection includes)
		{
			base.RegisterIncludes(includes);

			if (this.TPage != null)
			{
				includes.Add(new StyleResourceInclude("TA.Turbo.Res.CSS.TreeView.css", typeof(TreeView)));

				includes.Add(Script.ElementSearch);
				includes.Add(Script.Template);
				includes.Add(Script.String_HTMLEncode);
				includes.Add(Script.Element_HasClass);
				includes.Add(Script.Element_AddClass);
				includes.Add(Script.Array_Remove);
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.TreeNodeType.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.TreeNodePosition.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.TreeNodeContainer.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.TreeNodeCollection.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.BaseTreeNode.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.BaseTextNode.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.HyperLinkNode.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.SelectionNode.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.TemplateNode.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.ExpansionNode.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.CheckBoxNode.js", typeof(TreeView)));
				includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.TreeView.TreeView.js", typeof(TreeView)));

				this.TPage.ClientScript.RegisterStyleBlock("TreeView", string.Format(
					"div.tv_node {{ background-image: url('{0}'); }}",
					this.TPage.ClientScript.GetWebResourceUrl(
						typeof(TreeView),
						"TA.Turbo.Res.Img.TreeView.node_bg.png")
					));

				this.TPage.ClientScript.RegisterClientScriptBlock(typeof(TreeView), "Images",
					TPage.PrepareScript(string.Format(
						"var __TVCollapsed = \"{0}\", __TVExpanded = \"{1}\", __TVLeaf = \"{2}\";"
						, this.TPage.ClientScript.GetWebResourceUrl(typeof(BaseTreeNode), "TA.Turbo.Res.Img.TreeView.node_collapsed.png")
						, this.TPage.ClientScript.GetWebResourceUrl(typeof(BaseTreeNode), "TA.Turbo.Res.Img.TreeView.node_expanded.png")
						, this.TPage.ClientScript.GetWebResourceUrl(typeof(BaseTreeNode), "TA.Turbo.Res.Img.TreeView.node_leaf.png"))),
					true);
			}
		}
		#endregion
		#region RENDER
		public override void RenderInitScriptInternal(HtmlTextWriter writer, string varName)
		{
			base.RenderInitScriptInternal(writer, varName);

			writer.Write(TPage.PrepareScript(string.Format("{0}.get_Templates().Deserialize(", varName)));
			JsonWriter jw = new JsonWriter(writer);
			this.Templates.Serialize(jw);
			writer.Write(");");

			//writer.Write("{0}.
		}
		//private void RenderInitScriptProperty(HtmlTextWriter writer, string varName, string propName, IJsonSerializable value)
		//{
		//  writer.Write("{0}.set_{1}Serialized(", varName, propName);
		//  JsonWriter jw = new JsonWriter(writer);
		//  this.Templates.Serialize(jw);
		//  writer.Write(");");
		//}
		protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
		{
			writer.AddAttribute(HtmlTextWriterAttribute.Class, "tv_list");
			writer.RenderBeginTag(HtmlTextWriterTag.Div);

			for (int i = 0; i < this.Nodes.Count; ++i)
			{
				BaseTreeNode node = this.Nodes[i];

				TreeNodePosition position = TreeNodePosition.RootRegular;
				if (this.Nodes.Count == 1)
				{
					position = TreeNodePosition.RootOnly;
				}
				else if (i == 0)
				{
					position = TreeNodePosition.RootFirst;
				}
				else if (i == this.Nodes.Count - 1)
				{
					position = TreeNodePosition.RootLast;
				}

				node.Render(this, position, 0, writer);
			}

			writer.RenderEndTag();
		}
		internal string GetNextTemplateNodeId()
		{
			return (++this._templateNodeId).ToString();
		}
		#endregion
		#region EVNETS
		public override void RaiseEvent(string name, string argument)
		{
			switch (name)
			{
				case "LoadNodes":
					using (StringReader sr = new StringReader(argument))
					{
						LoadNodesEventArgs e = new LoadNodesEventArgs(new JsonReader(sr));
						this.OnLoadNodes(e);

						for (int i = 0; i < e.Result.Count; ++i)
						{
							if (e.Exclude.Contains(e.Result[i].UniqueId))
							{
								e.Result.RemoveAt(i);
								--i;
							}
						}

						this.TPage.ResultMain = e.Result;
					}
					break;
				default:
					base.RaiseEvent(name, argument);
					break;
			}
		}

		protected virtual void OnLoadNodes(LoadNodesEventArgs e)
		{
			this.LoadNodes.Raise(this, e);
		}
		#endregion
		#endregion
		#endregion
	}
}
